<?php
$nosession = true;
@header('Content-Type: application/json; charset=UTF-8');
// 引入数据库初始化文件
require_once './includes/common.php';

class Sapi
{
    public function run()
    {
        $act = trim($_GET['act']);
        if (empty($act)) {
            echo json_encode(['code' => -1, 'msg' => '操作类型不能为空！']);
            return;
        }
        if (method_exists(__CLASS__, $act)) {
            $result = $this->$act();
            echo json_encode($result);
        } else {
            echo json_encode(['code' => -1, 'msg' => '无效的操作类型！']);
        }
    }

    // 平台开商户接口
    public function add()
    {
        global $DB; // 全局变量，定义在./includes/common.php中

        $partner_id = trim($_POST['partnerId']);
        $phone = trim($_POST['phone']);
        $email = trim($_POST['email']);
        $pwd = trim($_POST['pwd']);
        $account = trim($_POST['account']);
        $username = trim($_POST['username']);
        $sign = trim($_POST['sign']);
        $sign_type = trim($_POST['signType']) ?? 'MD5';

        if (empty($account) || empty($username) || empty($partner_id) || empty($sign)) {
            return ['code' => -1, 'msg' => '必填项不能为空！'];
        }

        // 验证签名
        $partner_conf = $DB->find('partner', '*', ['id' => $partner_id]);
        if (empty($partner_conf)) {
            return ['code' => -1, 'msg' => '合作商不存在！'];
        }
        if (!$this->verifySign($_POST, $partner_conf['sign_key'], $partner_conf['public_key'])) {
            return ['code' => -1, 'msg' => '签名验证失败！'];
        }

        // 检查手机号和邮箱是否已存在
        if (!empty($phone) && $DB->find('user', '*', ['phone' => $phone])) {
            return ['code' => -1, 'msg' => '手机号已存在！'];
        }
        if (!empty($email) && $DB->find('user', '*', ['email' => $email])) {
            return ['code' => -1, 'msg' => '邮箱已存在！'];
        }

        // 插入新商户
        $key = $this->random(32); // 生成随机密钥
        $data = [
            'gid' => intval($_POST['gid']), // 用户组id
            'key' => $key,
            'settle_id' => intval($_POST['settle_id']), // 余额结算方式id 1-支付宝，2-微信，3-QQ钱包，4-银行卡
            'account' => $account, // 商户结算账号
            'username' => $username, // 商户结算姓名
            'money' => '0.00', // 商户余额
            'url' => trim($_POST['url']) ?? '', // 网站域名
            'email' => $email, // 邮箱
            'qq' => trim($_POST['qq']),
            'phone' => $phone,
            'mode' => 1,
            'cert' => 0,
            'pay' => 1,
            'settle' => intval($_POST['settle']), // 手续费结算方式 1-余额扣费,商户后台->余额充值，2-订单加费
            'status' => 1, // 默认状态为启用 0-禁用 1-正常 2-未审核
            'addtime' => date("Y-m-d H:i:s"),
            'from_partner' => $partner_id,
        ];

        $uid = $DB->insert('user', $data);
        if ($uid !== false) {
            if (!empty($pwd)) {
                $pwd = getMd5Pwd($pwd, $uid); // 密码加密
                $DB->update('user', ['pwd' => $pwd], ['uid' => $uid]);
            }
            // 返回结果
            $result['code'] = 0;
            $result['uid'] = $uid;
            $result['key'] = $key;
            $result['timestamp'] = time() . '';
            $result['signType'] = 'MD5';

            // 读取数据库中合作商的公钥私钥等
            $partner_conf = $DB->find('partner', '*', ['id' => $partner_id]);
            // 生成签名
            $result['sign'] = $this->makeSign($result, $partner_conf['sign_key'], $partner_conf['private_key']);
            return $result;
        } else {
            return ['code' => -1, 'msg' => '添加商户失败！' . $DB->error()];
        }
    }

    // 生成随机字符串
    public function random($length, $numeric = 0)
    {
        $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
        $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
        $hash = '';
        $max = strlen($seed) - 1;
        for ($i = 0; $i < $length; $i++) {
            $hash .= $seed[mt_rand(0, $max)];
        }
        return $hash;
    }

    //生成待签名字符串
    private function getSignContent($data)
    {
        ksort($data);
        $signStr = '';
        foreach ($data as $k => $v) {
            if (is_array($v) || isEmpty($v) || $k == 'sign' || $k == 'sign_type') {
                continue;
            }

            $signStr .= $k . '=' . $v . '&';
        }
        $signStr = substr($signStr, 0, -1);
        return $signStr;
    }

    //生成签名
    public function makeSign($data, $md5key, $private_key)
    {
        $sign_type = $data['signType'] ?? 'MD5';
        $signStr = $this->getSignContent($data);
        if ($sign_type == 'RSA') {
            $private_key = base64ToPem($partner_conf['private_key'], 'PRIVATE KEY');
            $pkey = openssl_pkey_get_private($private_key);
            if (!$pkey) {
                return false;
            }

            openssl_sign($signStr, $sign, $pkey, OPENSSL_ALGO_SHA256);
            return base64_encode($sign);
        } else {
            $sign = md5($signStr . $md5key);
            return $sign;
        }
    }

    //验证签名
    public function verifySign($data, $md5key, $publicKey)
    {
        if (!isset($data['sign'])) {
            throw new Exception('缺少签名参数');
        }

        $sign_type = $data['signType'] ?? 'MD5';
        if ($sign_type == 'RSA') {
            $public_key = base64ToPem($publicKey, 'PUBLIC KEY');
            $pkey = openssl_pkey_get_public($public_key);
            if (!$pkey) {
                throw new Exception('签名校验失败，商户公钥错误');
            }

            $signStr = $this->getSignContent($data);
            $result = openssl_verify($signStr, base64_decode($data['sign']), $pkey, OPENSSL_ALGO_SHA256);
            return $result === 1;
        } else {
            $sign = $this->makeSign($data, $md5key, null);
            return $sign === $data['sign'];
        }
    }
}

$sapi = new Sapi();
$sapi->run();
